package com.poly_;

public class PolyObject {
    /**
     * 对象的多态：
     * 1.一个对象的编译类型和运行类型可以不一致
     * 2.编译类型在定义对象时，就确定了，不能改变
     * 3.运行类型是可以变化的
     * 4.编译类型看定义时 = 号的左边，运行类型看 = 号 的右边
     * 5.访问属性时要看对象的编译类型
     */
    public static void main(String[] args) {
        Mater jack = new Mater("jack");
        /**父类引用指向子类对象称之为向上转型
         语法：父类类型引用名 = new 子类类型();
         可以调用父类所有成员，但必须遵守访问权限
         但不能调用子类特有的成员*/
        Animal animal = new Dog("大黄狗");
        //animal.age;-----错误，不能调用子类特有成员

        /**向下转型：
         * 1.语法：子类类型 引用名 = (子类类型)父类引用;
         * 2.只能强转父类的引用，不能强转父类的对象
         * 3.要求父类的引用必须指向的是当前父类转型的对象
         * 4.当向下转型后，可以调用子类类型中的所有成员
         */
        Food food = new Bone("大骨头");
        //food.AAA;错误，无法访问子类中的方法
        Bone bone = (Bone) food;//向下转型
        bone.AAA();//转型之后可以访问子类的成员
        //3.要求父类的引用必须指向的是当前父类转型的对象
        //Fish fish = (Fish) food;//编译不会报错，运行会出现类转换异常报错
        jack.say(animal, food);
        animal = new Cat("小花猫");
        food = new Fish("鱼");
        jack.say(animal, food);
    }
}
